#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <iostream>
#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>

#define CONNECTION_NUM 900

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pid_t *pids = nullptr;

void error_handling(const char *message)
{
    perror(message);
    exit(1);
}

void sig_func(int sig)
{
    if(pids)
    {
        for (int i = 0; i < CONNECTION_NUM; i++)
        {
            kill(pids[i], SIGKILL);
        }
    }
}

int main(int argc, char *argv[])
{
    struct sigaction siga;
    siga.sa_handler = sig_func;
    siga.sa_flags = 0;
    sigemptyset(&siga.sa_mask);
    sigaction(SIGINT, &siga, NULL);

    pids = new pid_t[CONNECTION_NUM];

    for (int i = 0; i < CONNECTION_NUM; i++)
    {
        int pid = fork();
        if (pid == 0)
        {
            int lfd = socket(PF_INET, SOCK_STREAM, 0);

            sockaddr_in addr_lfd;
            addr_lfd.sin_family = AF_INET;
            addr_lfd.sin_addr.s_addr = inet_addr("127.0.0.1");
            addr_lfd.sin_port = htons(6688);

            int ret = connect(lfd, (sockaddr *)&addr_lfd, sizeof(addr_lfd));
            if (ret == -1)
            {
                error_handling("connect socket error");
                exit(1);
            }
            // 测试
            // std::string test_str = "new connect " + std::to_string(i) + "\n";
            // int fdout = open("test.out", O_WRONLY | O_APPEND);
            // write(fdout, test_str.c_str(), test_str.size());
            // close(fdout);

            char buf[] = "test words...";
            while(1)
            {
                usleep(1e2);
                write(lfd, buf, sizeof(buf));
            }

            std::cout << "process " << getpid() << " exit." << std::endl;
            exit(1);
        }
        else
        {
            pids[i] = pid;
        }
    }

    int status;
    for (int i = 0; i < CONNECTION_NUM; i++)
    {
        wait(&status);
    }
    std::cout << "all child process exited..." << std::endl;

    delete[] pids;

    return 0;
}